package cn.iocoder.yudao.module.system.service.examscore;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.*;

/**
 * Excel格式检测器
 * 用于检测Excel文件是使用旧格式还是新格式
 */
@Slf4j
@Component
public class ExcelFormatDetector {

    /**
     * Excel格式枚举
     */
    public enum ExcelFormat {
        LEGACY,    // 旧格式 (ExamScoreImportExcelVO)
        EXTENDED   // 新格式 (ExtendedExamScoreImportExcelVO)
    }

    /**
     * 旧格式的关键字段
     */
    private static final Set<String> LEGACY_FORMAT_KEYWORDS = Set.of(
        "学号", "姓名", "语文", "数学", "英语", "物理", "化学", "生物", "政治", "历史", "地理", "总分"
    );

    /**
     * 新格式的关键字段
     */
    private static final Set<String> EXTENDED_FORMAT_KEYWORDS = Set.of(
        "准考证号", "班级", "选考科目", "原始分", "等级", "联考名次", "校次", "班次", 
        "方向名次", "选考名次", "总分", "选考总分", "方向总分", "主科总分",
        // 小语种关键字
        "俄语", "日语", "西班牙语",
        // 第一高分和第二高分关键字
        "第一高分", "第二高分", "第一", "第二", "高分"
    );

    /**
     * 检测Excel文件格式
     * 
     * @param inputStream Excel文件输入流
     * @return Excel格式类型
     */
    public ExcelFormat detectFormat(InputStream inputStream) {
        try {
            FormatDetectionListener listener = new FormatDetectionListener();
            EasyExcel.read(inputStream, listener).sheet().headRowNumber(1).doRead();
            return listener.getDetectedFormat();
        } catch (Exception e) {
            log.error("检测Excel格式时发生错误", e);
            // 默认返回旧格式
            return ExcelFormat.LEGACY;
        }
    }

    /**
     * 格式检测监听器
     */
    private static class FormatDetectionListener extends AnalysisEventListener<Map<Integer, String>> {
        
        private final List<String> headerRow = new ArrayList<>();
        private boolean headerProcessed = false;
        private ExcelFormat detectedFormat = ExcelFormat.LEGACY;

        @Override
        public void invoke(Map<Integer, String> data, AnalysisContext context) {
            // 只处理第一行（标题行）
            if (!headerProcessed) {
                // 收集标题行数据
                for (Map.Entry<Integer, String> entry : data.entrySet()) {
                    String value = entry.getValue();
                    if (value != null && !value.trim().isEmpty()) {
                        headerRow.add(value.trim());
                    }
                }
                headerProcessed = true;
                
                // 分析格式
                analyzeFormat();
            }
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            // 分析完成后的处理
            if (!headerProcessed) {
                analyzeFormat();
            }
        }

        /**
         * 分析Excel格式
         */
        private void analyzeFormat() {
            if (headerRow.isEmpty()) {
                detectedFormat = ExcelFormat.LEGACY;
                return;
            }

            // 统计匹配的关键字数量
            int legacyMatches = 0;
            int extendedMatches = 0;

            for (String header : headerRow) {
                // 检查是否匹配旧格式关键字
                for (String keyword : LEGACY_FORMAT_KEYWORDS) {
                    if (header.contains(keyword)) {
                        legacyMatches++;
                        break;
                    }
                }

                // 检查是否匹配新格式关键字
                for (String keyword : EXTENDED_FORMAT_KEYWORDS) {
                    if (header.contains(keyword)) {
                        extendedMatches++;
                        break;
                    }
                }
            }

            log.info("格式检测结果 - 旧格式匹配: {}, 新格式匹配: {}, 标题行: {}", 
                    legacyMatches, extendedMatches, headerRow);

            // 判断格式类型
            if (extendedMatches > legacyMatches && extendedMatches >= 3) {
                // 如果新格式匹配数更多且至少匹配3个关键字，则认为是新格式
                detectedFormat = ExcelFormat.EXTENDED;
            } else if (legacyMatches >= 3) {
                // 如果旧格式匹配至少3个关键字，则认为是旧格式
                detectedFormat = ExcelFormat.LEGACY;
            } else {
                // 默认使用旧格式
                detectedFormat = ExcelFormat.LEGACY;
            }

            log.info("检测到的Excel格式: {}", detectedFormat);
        }

        public ExcelFormat getDetectedFormat() {
            return detectedFormat;
        }
    }

    /**
     * 检测Excel文件格式（通过标题行内容）
     * 
     * @param headers 标题行内容
     * @return Excel格式类型
     */
    public ExcelFormat detectFormatByHeaders(List<String> headers) {
        if (headers == null || headers.isEmpty()) {
            return ExcelFormat.LEGACY;
        }

        int legacyMatches = 0;
        int extendedMatches = 0;

        for (String header : headers) {
            if (header == null || header.trim().isEmpty()) {
                continue;
            }

            String trimmedHeader = header.trim();

            // 检查是否匹配旧格式关键字
            for (String keyword : LEGACY_FORMAT_KEYWORDS) {
                if (trimmedHeader.contains(keyword)) {
                    legacyMatches++;
                    break;
                }
            }

            // 检查是否匹配新格式关键字
            for (String keyword : EXTENDED_FORMAT_KEYWORDS) {
                if (trimmedHeader.contains(keyword)) {
                    extendedMatches++;
                    break;
                }
            }
        }

        log.info("标题行格式检测 - 旧格式匹配: {}, 新格式匹配: {}", legacyMatches, extendedMatches);

        // 判断格式类型
        if (extendedMatches > legacyMatches && extendedMatches >= 3) {
            return ExcelFormat.EXTENDED;
        } else if (legacyMatches >= 3) {
            return ExcelFormat.LEGACY;
        } else {
            return ExcelFormat.LEGACY;
        }
    }

    /**
     * 检查是否为新格式的特征字段
     */
    public boolean hasExtendedFormatFeatures(List<String> headers) {
        if (headers == null || headers.isEmpty()) {
            return false;
        }

        // 检查是否包含新格式的特征字段
        for (String header : headers) {
            if (header != null) {
                String trimmedHeader = header.trim();
                if (trimmedHeader.contains("准考证号") || 
                    trimmedHeader.contains("选考科目") ||
                    trimmedHeader.contains("联考名次") ||
                    trimmedHeader.contains("原始分") ||
                    trimmedHeader.contains("等级") ||
                    trimmedHeader.contains("方向名次") ||
                    // 小语种字段
                    trimmedHeader.contains("俄语") ||
                    trimmedHeader.contains("日语") ||
                    trimmedHeader.contains("西班牙语") ||
                    // 第一高分和第二高分字段
                    trimmedHeader.contains("第一高分") ||
                    trimmedHeader.contains("第二高分")) {
                    return true;
                }
            }
        }
        return false;
    }
}